package com.hn.common.utils.sql;


import com.google.common.base.CaseFormat;
import com.hn.common.exception.BusinessException;
import com.hn.common.utils.StringUtils;
import com.hn.common.utils.reflect.ReflectUtils;
import tk.mybatis.mapper.entity.Example;

import javax.persistence.Transient;
import java.lang.reflect.Field;
import java.util.List;

/**
 * sql操作工具类
 *
 * @author ruoyi
 */
public class SqlUtil {

    private SqlUtil(){}

    /**
     * 仅支持字母、数字、下划线、空格、逗号（支持多个字段排序）
     */
    public static String SQL_PATTERN = "[a-zA-Z0-9_\\ \\,]+";

    /**
     * 检查字符，防止注入绕过
     */
    public static String escapeOrderBySql(String value) {
        if (StringUtils.isNotEmpty(value) && !isValidOrderBySql(value)) {
            return StringUtils.EMPTY;
        }
        return value;
    }

    /**
     * 下划线转驼峰
     */
    public static String lineToHump(String str) {
        return CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, str);
    }

    /**
     * 驼峰转下划线,效率比上面高
     */
    public static String humpToLine(String str) {
        return CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, str);
    }

    /**
     * 验证 order by 语法是否符合规范
     */
    public static boolean isValidOrderBySql(String value) {
        return value.matches(SQL_PATTERN);
    }


    /**
     * 构建example查询
     */
    public static Example newExample(Class clazz) {
        System.out.println("################# clazz:"+clazz);
        if (clazz == null) {
            throw new BusinessException("网络错误,请刷新再试");
        }

        return new Example(clazz, true, true);
    }

    public static Example newExample(Object obj) {
        if (obj == null) {
            throw new BusinessException("网络错误,请刷新再试");
        }

        Class<?> clazz = obj.getClass();
        Example example = new Example(clazz);
        Example.Criteria criteria = example.createCriteria();

        Field[] allFields = clazz.getDeclaredFields();
        for (Field field : allFields) {
            Transient aTransient = field.getAnnotation(Transient.class);
            if (aTransient != null) {
                continue;
            }

            String name = field.getName();
            if ("serialVersionUID".equals(name)) {
                continue;
            }

            Object val = ReflectUtils.getFieldValue(obj, name);
            if (val == null) {
                continue;
            }

            Class<?> type = field.getType();
            if (type.equals(String.class)) {
                if (StringUtils.isBlank((String) val)) {
                    continue;
                }
            }
            criteria.andEqualTo(name, val);
        }
        // 如果criteria.getCriteria为null,就清空
        if (criteria.getCriteria().size() == 0) {
            example.clear();
        }
        return example;
    }

    public static Example.Criteria createCriteria(Example example) {
        if (example == null) {
            throw new BusinessException("example is null");
        }
        List<Example.Criteria> oredCriteria = example.getOredCriteria();
        if (oredCriteria == null || oredCriteria.isEmpty()) {
            throw new BusinessException("example is null");
        }
        return oredCriteria.get(0);
    }

}
